﻿using Inaction;
using Inaction.Core;
using Inaction.Linq.Clause;
using Inaction.Mapping;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Runtime.Serialization;
using System.Text;

namespace Inaction.Linq
{
    [Serializable]
    class LinqParse
    {
        internal static WhereClause Parse(Expression e, LinqRoot root)
        {
            if (e is LambdaExpression)
            {
                var lambda = e as LambdaExpression;
                var temp = new LinqRoot(lambda, root);
                return Parse(lambda.Body, temp);
            }
            if (e is BinaryExpression)
            {
                return ParseBinary((BinaryExpression)e, root);
            }
            if (e is MethodCallExpression)
            {
                return ParseMethodCall((MethodCallExpression)e, root);
            }
            if (e is UnaryExpression)
            {
                return ParseUnary((UnaryExpression)e, root);
            }
            if (e is MemberExpression)
            {
                return new MemberClause(root, e as System.Linq.Expressions.MemberExpression);
            }
            if (e is ConstantExpression)
            {
                return new ConstantClause(root, e as System.Linq.Expressions.ConstantExpression);
            }
            throw new Exception("Not supported operation!");
        }

        internal static WhereClause ParseBinary(BinaryExpression e, LinqRoot root)
        {
            switch (e.NodeType)
            {
                case ExpressionType.Equal:
                    return new EqualCluase(root, e);
                case ExpressionType.GreaterThan:
                    return new GreatThanClause(root, e);
                case ExpressionType.GreaterThanOrEqual:
                    return new GreatOrEqualClause(root, e);
                case ExpressionType.LessThan:
                    return new LessThanClause(root, e);
                case ExpressionType.LessThanOrEqual:
                    return new LessOrEqualClause(root, e);
                case ExpressionType.NotEqual:
                    return new NotEqualClause(root, e);
                case ExpressionType.AndAlso:
                    return new AndClause(root, e);
                case ExpressionType.OrElse:
                    return new OrClause(root, e);
                default:
                    throw new Exception("Not supported operation!");
            }
        }

        internal static WhereClause ParseMethodCall(MethodCallExpression e, LinqRoot root)
        {
            return new MethodCallClause(root, e);
        }

        internal static WhereClause ParseUnary(UnaryExpression e, LinqRoot root)
        {
            return new UnaryClause(root, e);
        }

        internal static bool IsBooleanFieldOrProperty(Expression e)
        {
            if (e is MemberExpression)
            {
                var member = ((MemberExpression)e);
                IProperty p = null;
                if (member.Expression is MemberExpression)
                {
                    var memberExpress = member.Expression as MemberExpression;
                    p = ClassInfo.GetProperty(memberExpress.Expression.Type, memberExpress.Member.Name);
                }
                else
                {
                    p = ClassInfo.GetProperty(member.Expression.Type, member.Member.Name);
                }
                return p.UnderlyingType == typeof(bool);
            }
            return false;
        }
    }
}
